//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension Grafana {
    // MARK: Enums

    public enum AccountAccessType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        /// Indicates that the customer is using Grafana to monitor resources in their current account.
        case currentAccount = "CURRENT_ACCOUNT"
        /// Indicates that the customer is using Grafana to monitor resources in organizational units.
        case organization = "ORGANIZATION"
        public var description: String { return self.rawValue }
    }

    public enum AuthenticationProviderTypes: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        /// Indicates that AMG workspace has AWS SSO enabled as its authentication provider.
        case awsSso = "AWS_SSO"
        /// Indicates that the AMG workspace has SAML enabled as its authentication provider.
        case saml = "SAML"
        public var description: String { return self.rawValue }
    }

    public enum DataSourceType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        /// Amazon OpenSearch Service
        case amazonOpensearchService = "AMAZON_OPENSEARCH_SERVICE"
        /// Amazon Athena
        case athena = "ATHENA"
        /// CloudWatch Logs
        case cloudwatch = "CLOUDWATCH"
        /// Managed Prometheus
        case prometheus = "PROMETHEUS"
        /// Redshift
        case redshift = "REDSHIFT"
        /// IoT SiteWise
        case sitewise = "SITEWISE"
        /// Timestream
        case timestream = "TIMESTREAM"
        /// IoT TwinMaker
        case twinmaker = "TWINMAKER"
        /// X-Ray
        case xray = "XRAY"
        public var description: String { return self.rawValue }
    }

    public enum LicenseType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        /// Grafana Enterprise License.
        case enterprise = "ENTERPRISE"
        /// Grafana Enterprise Free Trial License.
        case enterpriseFreeTrial = "ENTERPRISE_FREE_TRIAL"
        public var description: String { return self.rawValue }
    }

    public enum NotificationDestinationType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        /// AWS Simple Notification Service
        case sns = "SNS"
        public var description: String { return self.rawValue }
    }

    public enum PermissionType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        /// Customer Managed
        case customerManaged = "CUSTOMER_MANAGED"
        /// Service Managed
        case serviceManaged = "SERVICE_MANAGED"
        public var description: String { return self.rawValue }
    }

    public enum Role: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        /// Role Admin.
        case admin = "ADMIN"
        /// Role Editor.
        case editor = "EDITOR"
        /// Role Viewer.
        case viewer = "VIEWER"
        public var description: String { return self.rawValue }
    }

    public enum SamlConfigurationStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        /// Indicates that SAML on an AMG workspace is enabled and has been configured.
        case configured = "CONFIGURED"
        /// Indicates that SAML on an AMG workspace is enabled but has not been configured.
        case notConfigured = "NOT_CONFIGURED"
        public var description: String { return self.rawValue }
    }

    public enum UpdateAction: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        /// Add permissions.
        case add = "ADD"
        /// Revoke permissions.
        case revoke = "REVOKE"
        public var description: String { return self.rawValue }
    }

    public enum UserType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        /// SSO group.
        case ssoGroup = "SSO_GROUP"
        /// SSO user.
        case ssoUser = "SSO_USER"
        public var description: String { return self.rawValue }
    }

    public enum ValidationExceptionReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case cannotParse = "CANNOT_PARSE"
        case fieldValidationFailed = "FIELD_VALIDATION_FAILED"
        case other = "OTHER"
        case unknownOperation = "UNKNOWN_OPERATION"
        public var description: String { return self.rawValue }
    }

    public enum WorkspaceStatus: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        /// Workspace is active.
        case active = "ACTIVE"
        /// Workspace is being created.
        case creating = "CREATING"
        /// Workspace creation failed.
        case creationFailed = "CREATION_FAILED"
        /// Workspace is being deleted.
        case deleting = "DELETING"
        /// Workspace deletion failed.
        case deletionFailed = "DELETION_FAILED"
        /// Workspace is in an invalid state, it can only and should be deleted.
        case failed = "FAILED"
        /// Failed to remove enterprise license from workspace.
        case licenseRemovalFailed = "LICENSE_REMOVAL_FAILED"
        /// Workspace update failed.
        case updateFailed = "UPDATE_FAILED"
        /// Workspace is being updated.
        case updating = "UPDATING"
        /// Workspace upgrade failed.
        case upgradeFailed = "UPGRADE_FAILED"
        /// Workspace is being upgraded to enterprise.
        case upgrading = "UPGRADING"
        /// Workspace version update failed.
        case versionUpdateFailed = "VERSION_UPDATE_FAILED"
        /// Workspace version is being updated.
        case versionUpdating = "VERSION_UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum IdpMetadata: AWSEncodableShape & AWSDecodableShape, Sendable {
        /// The URL of the location containing the IdP metadata.
        case url(String)
        /// The full IdP metadata, in XML format.
        case xml(String)

        public init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            guard container.allKeys.count == 1, let key = container.allKeys.first else {
                let context = DecodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Expected exactly one key, but got \(container.allKeys.count)"
                )
                throw DecodingError.dataCorrupted(context)
            }
            switch key {
            case .url:
                let value = try container.decode(String.self, forKey: .url)
                self = .url(value)
            case .xml:
                let value = try container.decode(String.self, forKey: .xml)
                self = .xml(value)
            }
        }

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .url(let value):
                try container.encode(value, forKey: .url)
            case .xml(let value):
                try container.encode(value, forKey: .xml)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .url(let value):
                try self.validate(value, name: "url", parent: name, max: 2048)
                try self.validate(value, name: "url", parent: name, min: 1)
            default:
                break
            }
        }

        private enum CodingKeys: String, CodingKey {
            case url = "url"
            case xml = "xml"
        }
    }

    // MARK: Shapes

    public struct AssertionAttributes: AWSEncodableShape & AWSDecodableShape {
        /// The name of the attribute within the SAML assertion to use as the email names for SAML users.
        public let email: String?
        /// The name of the attribute within the SAML assertion to use as the user full "friendly" names for user groups.
        public let groups: String?
        /// The name of the attribute within the SAML assertion to use as the login names for SAML users.
        public let login: String?
        /// The name of the attribute within the SAML assertion to use as the user full "friendly" names for SAML users.
        public let name: String?
        /// The name of the attribute within the SAML assertion to use as the user full "friendly" names for the users' organizations.
        public let org: String?
        /// The name of the attribute within the SAML assertion to use as the user roles.
        public let role: String?

        @inlinable
        public init(email: String? = nil, groups: String? = nil, login: String? = nil, name: String? = nil, org: String? = nil, role: String? = nil) {
            self.email = email
            self.groups = groups
            self.login = login
            self.name = name
            self.org = org
            self.role = role
        }

        public func validate(name: String) throws {
            try self.validate(self.email, name: "email", parent: name, max: 256)
            try self.validate(self.email, name: "email", parent: name, min: 1)
            try self.validate(self.groups, name: "groups", parent: name, max: 256)
            try self.validate(self.groups, name: "groups", parent: name, min: 1)
            try self.validate(self.login, name: "login", parent: name, max: 256)
            try self.validate(self.login, name: "login", parent: name, min: 1)
            try self.validate(self.name, name: "name", parent: name, max: 256)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.org, name: "org", parent: name, max: 256)
            try self.validate(self.org, name: "org", parent: name, min: 1)
            try self.validate(self.role, name: "role", parent: name, max: 256)
            try self.validate(self.role, name: "role", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case email = "email"
            case groups = "groups"
            case login = "login"
            case name = "name"
            case org = "org"
            case role = "role"
        }
    }

    public struct AssociateLicenseRequest: AWSEncodableShape {
        /// A token from Grafana Labs that ties your Amazon Web Services account with a Grafana  Labs account. For more information, see Link your account with Grafana Labs.
        public let grafanaToken: String?
        /// The type of license to associate with the workspace.  Amazon Managed Grafana workspaces no longer support Grafana Enterprise free trials.
        public let licenseType: LicenseType
        /// The ID of the workspace to associate the license with.
        public let workspaceId: String

        @inlinable
        public init(grafanaToken: String? = nil, licenseType: LicenseType, workspaceId: String) {
            self.grafanaToken = grafanaToken
            self.licenseType = licenseType
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeHeader(self.grafanaToken, key: "Grafana-Token")
            request.encodePath(self.licenseType, key: "licenseType")
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.grafanaToken, name: "grafanaToken", parent: name, max: 36)
            try self.validate(self.grafanaToken, name: "grafanaToken", parent: name, min: 1)
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct AssociateLicenseResponse: AWSDecodableShape {
        /// A structure containing data about the workspace.
        public let workspace: WorkspaceDescription

        @inlinable
        public init(workspace: WorkspaceDescription) {
            self.workspace = workspace
        }

        private enum CodingKeys: String, CodingKey {
            case workspace = "workspace"
        }
    }

    public struct AuthenticationDescription: AWSDecodableShape {
        /// A structure containing information about how this workspace works with IAM Identity Center.
        public let awsSso: AwsSsoAuthentication?
        /// Specifies whether this workspace uses IAM Identity Center, SAML, or both methods to authenticate users to use the Grafana console in the Amazon Managed Grafana workspace.
        public let providers: [AuthenticationProviderTypes]
        /// A structure containing information about how this workspace works with SAML, including what attributes within the assertion are to be mapped to user information in the workspace.
        public let saml: SamlAuthentication?

        @inlinable
        public init(awsSso: AwsSsoAuthentication? = nil, providers: [AuthenticationProviderTypes], saml: SamlAuthentication? = nil) {
            self.awsSso = awsSso
            self.providers = providers
            self.saml = saml
        }

        private enum CodingKeys: String, CodingKey {
            case awsSso = "awsSso"
            case providers = "providers"
            case saml = "saml"
        }
    }

    public struct AuthenticationSummary: AWSDecodableShape {
        /// Specifies whether the workspace uses SAML, IAM Identity Center, or both methods for user authentication.
        public let providers: [AuthenticationProviderTypes]
        /// Specifies whether the workplace's user authentication method is fully configured.
        public let samlConfigurationStatus: SamlConfigurationStatus?

        @inlinable
        public init(providers: [AuthenticationProviderTypes], samlConfigurationStatus: SamlConfigurationStatus? = nil) {
            self.providers = providers
            self.samlConfigurationStatus = samlConfigurationStatus
        }

        private enum CodingKeys: String, CodingKey {
            case providers = "providers"
            case samlConfigurationStatus = "samlConfigurationStatus"
        }
    }

    public struct AwsSsoAuthentication: AWSDecodableShape {
        /// The ID of the IAM Identity Center-managed application that is created by Amazon Managed Grafana.
        public let ssoClientId: String?

        @inlinable
        public init(ssoClientId: String? = nil) {
            self.ssoClientId = ssoClientId
        }

        private enum CodingKeys: String, CodingKey {
            case ssoClientId = "ssoClientId"
        }
    }

    public struct ConflictException: AWSErrorShape {
        /// A description of the error.
        public let message: String
        /// The ID of the resource that is associated with the error.
        public let resourceId: String
        /// The type of the resource that is associated with the error.
        public let resourceType: String

        @inlinable
        public init(message: String, resourceId: String, resourceType: String) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct CreateWorkspaceApiKeyRequest: AWSEncodableShape {
        /// Specifies the name of the key. Keynames must be unique to the workspace.
        public let keyName: String
        /// Specifies the permission level of the key. Valid values: ADMIN|EDITOR|VIEWER
        public let keyRole: String
        /// Specifies the time in seconds until the key expires. Keys can be valid for up to 30 days.
        public let secondsToLive: Int
        /// The ID of the workspace to create an API key.
        public let workspaceId: String

        @inlinable
        public init(keyName: String, keyRole: String, secondsToLive: Int, workspaceId: String) {
            self.keyName = keyName
            self.keyRole = keyRole
            self.secondsToLive = secondsToLive
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.keyName, forKey: .keyName)
            try container.encode(self.keyRole, forKey: .keyRole)
            try container.encode(self.secondsToLive, forKey: .secondsToLive)
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.keyName, name: "keyName", parent: name, max: 100)
            try self.validate(self.keyName, name: "keyName", parent: name, min: 1)
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: String, CodingKey {
            case keyName = "keyName"
            case keyRole = "keyRole"
            case secondsToLive = "secondsToLive"
        }
    }

    public struct CreateWorkspaceApiKeyResponse: AWSDecodableShape {
        /// The key token. Use this value as a bearer token to authenticate HTTP requests to the workspace.
        public let key: String
        /// The name of the key that was created.
        public let keyName: String
        /// The ID of the workspace that the key is valid for.
        public let workspaceId: String

        @inlinable
        public init(key: String, keyName: String, workspaceId: String) {
            self.key = key
            self.keyName = keyName
            self.workspaceId = workspaceId
        }

        private enum CodingKeys: String, CodingKey {
            case key = "key"
            case keyName = "keyName"
            case workspaceId = "workspaceId"
        }
    }

    public struct CreateWorkspaceRequest: AWSEncodableShape {
        /// Specifies whether the workspace can access Amazon Web Services resources in this Amazon Web Services account only, or whether it can also access Amazon Web Services resources in other accounts in the same organization. If you specify ORGANIZATION, you must specify which organizational units the workspace can access in the workspaceOrganizationalUnits parameter.
        public let accountAccessType: AccountAccessType
        /// Specifies whether this workspace uses SAML 2.0, IAM Identity Center, or both to authenticate users for using the Grafana console within a workspace. For more information, see User authentication in Amazon Managed Grafana.
        public let authenticationProviders: [AuthenticationProviderTypes]
        /// A unique, case-sensitive, user-provided identifier to ensure the idempotency of the request.
        public let clientToken: String?
        /// The configuration string for the workspace that you create. For more information about the format and configuration options available, see Working in your Grafana workspace.
        public let configuration: String?
        /// Specifies the version of Grafana to support in the new workspace. If not specified,  defaults to the latest version (for example, 10.4). To get a list of supported versions, use the ListVersions operation.
        public let grafanaVersion: String?
        /// Configuration for network access to your workspace. When this is configured, only listed IP addresses and VPC endpoints will be able to access your workspace. Standard Grafana authentication and authorization will still be required. If this is not configured, or is removed, then all IP addresses and VPC endpoints will be allowed. Standard Grafana authentication and authorization will still be required.
        public let networkAccessControl: NetworkAccessConfiguration?
        /// The name of an IAM role that already exists to use with Organizations to access Amazon Web Services data sources and notification channels in other accounts in an organization.
        public let organizationRoleName: String?
        /// When creating a workspace through the Amazon Web Services API, CLI or Amazon Web Services CloudFormation, you must manage IAM roles and provision the permissions that the workspace needs to use Amazon Web Services data sources and notification channels. You must also specify a workspaceRoleArn for a role that you will manage for the workspace to use when accessing those datasources and notification  channels. The ability for Amazon Managed Grafana to create and update IAM roles on behalf of the user is supported only in the Amazon Managed Grafana console, where this value may be set to SERVICE_MANAGED.  Use only the CUSTOMER_MANAGED permission type when creating a workspace with the API, CLI or Amazon Web Services CloudFormation.   For more information, see Amazon Managed Grafana permissions and policies for Amazon Web Services data sources and notification channels.
        public let permissionType: PermissionType
        /// The name of the CloudFormation stack set to use to generate IAM roles to be used for this workspace.
        public let stackSetName: String?
        /// The list of tags associated with the workspace.
        public let tags: [String: String]?
        /// The configuration settings for an Amazon VPC that contains data sources for your Grafana workspace to connect to.  Connecting to a private VPC is not yet available in the Asia Pacific (Seoul)  Region (ap-northeast-2).
        public let vpcConfiguration: VpcConfiguration?
        /// This parameter is for internal use only, and should not be used.
        public let workspaceDataSources: [DataSourceType]?
        /// A description for the workspace. This is used only to help you identify this workspace. Pattern: ^[\\p{L}\\p{Z}\\p{N}\\p{P}]{0,2048}$
        public let workspaceDescription: String?
        /// The name for the workspace. It does not have to be unique.
        public let workspaceName: String?
        /// Specify the Amazon Web Services notification channels that you plan to use in this workspace. Specifying these data sources here enables Amazon Managed Grafana to create IAM roles and permissions that allow Amazon Managed Grafana to use these channels.
        public let workspaceNotificationDestinations: [NotificationDestinationType]?
        /// Specifies the organizational units that this workspace is allowed to use data sources from, if this workspace is in an account that is part of an organization.
        public let workspaceOrganizationalUnits: [String]?
        /// Specified the IAM role that grants permissions to the Amazon Web Services resources that the workspace will view data from, including both data  sources and notification channels. You are responsible for managing the permissions  for this role as new data sources or notification channels are added.
        public let workspaceRoleArn: String?

        @inlinable
        public init(accountAccessType: AccountAccessType, authenticationProviders: [AuthenticationProviderTypes], clientToken: String? = CreateWorkspaceRequest.idempotencyToken(), configuration: String? = nil, grafanaVersion: String? = nil, networkAccessControl: NetworkAccessConfiguration? = nil, organizationRoleName: String? = nil, permissionType: PermissionType, stackSetName: String? = nil, tags: [String: String]? = nil, vpcConfiguration: VpcConfiguration? = nil, workspaceDataSources: [DataSourceType]? = nil, workspaceDescription: String? = nil, workspaceName: String? = nil, workspaceNotificationDestinations: [NotificationDestinationType]? = nil, workspaceOrganizationalUnits: [String]? = nil, workspaceRoleArn: String? = nil) {
            self.accountAccessType = accountAccessType
            self.authenticationProviders = authenticationProviders
            self.clientToken = clientToken
            self.configuration = configuration
            self.grafanaVersion = grafanaVersion
            self.networkAccessControl = networkAccessControl
            self.organizationRoleName = organizationRoleName
            self.permissionType = permissionType
            self.stackSetName = stackSetName
            self.tags = tags
            self.vpcConfiguration = vpcConfiguration
            self.workspaceDataSources = workspaceDataSources
            self.workspaceDescription = workspaceDescription
            self.workspaceName = workspaceName
            self.workspaceNotificationDestinations = workspaceNotificationDestinations
            self.workspaceOrganizationalUnits = workspaceOrganizationalUnits
            self.workspaceRoleArn = workspaceRoleArn
        }

        public func validate(name: String) throws {
            try self.validate(self.clientToken, name: "clientToken", parent: name, pattern: "^[!-~]{1,64}$")
            try self.validate(self.configuration, name: "configuration", parent: name, max: 65536)
            try self.validate(self.configuration, name: "configuration", parent: name, min: 2)
            try self.validate(self.grafanaVersion, name: "grafanaVersion", parent: name, max: 255)
            try self.validate(self.grafanaVersion, name: "grafanaVersion", parent: name, min: 1)
            try self.networkAccessControl?.validate(name: "\(name).networkAccessControl")
            try self.validate(self.organizationRoleName, name: "organizationRoleName", parent: name, max: 2048)
            try self.validate(self.organizationRoleName, name: "organizationRoleName", parent: name, min: 1)
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
            try self.vpcConfiguration?.validate(name: "\(name).vpcConfiguration")
            try self.validate(self.workspaceDescription, name: "workspaceDescription", parent: name, max: 2048)
            try self.validate(self.workspaceName, name: "workspaceName", parent: name, pattern: "^[a-zA-Z0-9-._~]{1,255}$")
            try self.validate(self.workspaceRoleArn, name: "workspaceRoleArn", parent: name, max: 2048)
            try self.validate(self.workspaceRoleArn, name: "workspaceRoleArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case accountAccessType = "accountAccessType"
            case authenticationProviders = "authenticationProviders"
            case clientToken = "clientToken"
            case configuration = "configuration"
            case grafanaVersion = "grafanaVersion"
            case networkAccessControl = "networkAccessControl"
            case organizationRoleName = "organizationRoleName"
            case permissionType = "permissionType"
            case stackSetName = "stackSetName"
            case tags = "tags"
            case vpcConfiguration = "vpcConfiguration"
            case workspaceDataSources = "workspaceDataSources"
            case workspaceDescription = "workspaceDescription"
            case workspaceName = "workspaceName"
            case workspaceNotificationDestinations = "workspaceNotificationDestinations"
            case workspaceOrganizationalUnits = "workspaceOrganizationalUnits"
            case workspaceRoleArn = "workspaceRoleArn"
        }
    }

    public struct CreateWorkspaceResponse: AWSDecodableShape {
        /// A structure containing data about the workspace that was created.
        public let workspace: WorkspaceDescription

        @inlinable
        public init(workspace: WorkspaceDescription) {
            self.workspace = workspace
        }

        private enum CodingKeys: String, CodingKey {
            case workspace = "workspace"
        }
    }

    public struct CreateWorkspaceServiceAccountRequest: AWSEncodableShape {
        /// The permission level to use for this service account.  For more information about the roles and the permissions each has, see User roles in the Amazon Managed Grafana User Guide.
        public let grafanaRole: Role
        /// A name for the service account. The name must be unique within the workspace, as it determines the ID associated with the service account.
        public let name: String
        /// The ID of the workspace within which to create the service account.
        public let workspaceId: String

        @inlinable
        public init(grafanaRole: Role, name: String, workspaceId: String) {
            self.grafanaRole = grafanaRole
            self.name = name
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.grafanaRole, forKey: .grafanaRole)
            try container.encode(self.name, forKey: .name)
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: String, CodingKey {
            case grafanaRole = "grafanaRole"
            case name = "name"
        }
    }

    public struct CreateWorkspaceServiceAccountResponse: AWSDecodableShape {
        /// The permission level given to the service account.
        public let grafanaRole: Role
        /// The ID of the service account.
        public let id: String
        /// The name of the service account.
        public let name: String
        /// The workspace with which the service account is associated.
        public let workspaceId: String

        @inlinable
        public init(grafanaRole: Role, id: String, name: String, workspaceId: String) {
            self.grafanaRole = grafanaRole
            self.id = id
            self.name = name
            self.workspaceId = workspaceId
        }

        private enum CodingKeys: String, CodingKey {
            case grafanaRole = "grafanaRole"
            case id = "id"
            case name = "name"
            case workspaceId = "workspaceId"
        }
    }

    public struct CreateWorkspaceServiceAccountTokenRequest: AWSEncodableShape {
        /// A name for the token to create.
        public let name: String
        /// Sets how long the token will be valid, in seconds. You can set the time up to 30  days in the future.
        public let secondsToLive: Int
        /// The ID of the service account for which to create a token.
        public let serviceAccountId: String
        /// The ID of the workspace the service account resides within.
        public let workspaceId: String

        @inlinable
        public init(name: String, secondsToLive: Int, serviceAccountId: String, workspaceId: String) {
            self.name = name
            self.secondsToLive = secondsToLive
            self.serviceAccountId = serviceAccountId
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.name, forKey: .name)
            try container.encode(self.secondsToLive, forKey: .secondsToLive)
            request.encodePath(self.serviceAccountId, key: "serviceAccountId")
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, min: 1)
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: String, CodingKey {
            case name = "name"
            case secondsToLive = "secondsToLive"
        }
    }

    public struct CreateWorkspaceServiceAccountTokenResponse: AWSDecodableShape {
        /// The ID of the service account where the token was created.
        public let serviceAccountId: String
        /// Information about the created token, including the key. Be sure to store the key securely.
        public let serviceAccountToken: ServiceAccountTokenSummaryWithKey
        /// The ID of the workspace where the token was created.
        public let workspaceId: String

        @inlinable
        public init(serviceAccountId: String, serviceAccountToken: ServiceAccountTokenSummaryWithKey, workspaceId: String) {
            self.serviceAccountId = serviceAccountId
            self.serviceAccountToken = serviceAccountToken
            self.workspaceId = workspaceId
        }

        private enum CodingKeys: String, CodingKey {
            case serviceAccountId = "serviceAccountId"
            case serviceAccountToken = "serviceAccountToken"
            case workspaceId = "workspaceId"
        }
    }

    public struct DeleteWorkspaceApiKeyRequest: AWSEncodableShape {
        /// The name of the API key to delete.
        public let keyName: String
        /// The ID of the workspace to delete.
        public let workspaceId: String

        @inlinable
        public init(keyName: String, workspaceId: String) {
            self.keyName = keyName
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.keyName, key: "keyName")
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.keyName, name: "keyName", parent: name, max: 100)
            try self.validate(self.keyName, name: "keyName", parent: name, min: 1)
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteWorkspaceApiKeyResponse: AWSDecodableShape {
        /// The name of the key that was deleted.
        public let keyName: String
        /// The ID of the workspace where the key was deleted.
        public let workspaceId: String

        @inlinable
        public init(keyName: String, workspaceId: String) {
            self.keyName = keyName
            self.workspaceId = workspaceId
        }

        private enum CodingKeys: String, CodingKey {
            case keyName = "keyName"
            case workspaceId = "workspaceId"
        }
    }

    public struct DeleteWorkspaceRequest: AWSEncodableShape {
        /// The ID of the workspace to delete.
        public let workspaceId: String

        @inlinable
        public init(workspaceId: String) {
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteWorkspaceResponse: AWSDecodableShape {
        /// A structure containing information about the workspace that was deleted.
        public let workspace: WorkspaceDescription

        @inlinable
        public init(workspace: WorkspaceDescription) {
            self.workspace = workspace
        }

        private enum CodingKeys: String, CodingKey {
            case workspace = "workspace"
        }
    }

    public struct DeleteWorkspaceServiceAccountRequest: AWSEncodableShape {
        /// The ID of the service account to delete.
        public let serviceAccountId: String
        /// The ID of the workspace where the service account resides.
        public let workspaceId: String

        @inlinable
        public init(serviceAccountId: String, workspaceId: String) {
            self.serviceAccountId = serviceAccountId
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.serviceAccountId, key: "serviceAccountId")
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteWorkspaceServiceAccountResponse: AWSDecodableShape {
        /// The ID of the service account deleted.
        public let serviceAccountId: String
        /// The ID of the workspace where the service account was deleted.
        public let workspaceId: String

        @inlinable
        public init(serviceAccountId: String, workspaceId: String) {
            self.serviceAccountId = serviceAccountId
            self.workspaceId = workspaceId
        }

        private enum CodingKeys: String, CodingKey {
            case serviceAccountId = "serviceAccountId"
            case workspaceId = "workspaceId"
        }
    }

    public struct DeleteWorkspaceServiceAccountTokenRequest: AWSEncodableShape {
        /// The ID of the service account from which to delete the token.
        public let serviceAccountId: String
        /// The ID of the token to delete.
        public let tokenId: String
        /// The ID of the workspace from which to delete the token.
        public let workspaceId: String

        @inlinable
        public init(serviceAccountId: String, tokenId: String, workspaceId: String) {
            self.serviceAccountId = serviceAccountId
            self.tokenId = tokenId
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.serviceAccountId, key: "serviceAccountId")
            request.encodePath(self.tokenId, key: "tokenId")
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DeleteWorkspaceServiceAccountTokenResponse: AWSDecodableShape {
        /// The ID of the service account where the token was deleted.
        public let serviceAccountId: String
        /// The ID of the token that was deleted.
        public let tokenId: String
        /// The ID of the workspace where the token was deleted.
        public let workspaceId: String

        @inlinable
        public init(serviceAccountId: String, tokenId: String, workspaceId: String) {
            self.serviceAccountId = serviceAccountId
            self.tokenId = tokenId
            self.workspaceId = workspaceId
        }

        private enum CodingKeys: String, CodingKey {
            case serviceAccountId = "serviceAccountId"
            case tokenId = "tokenId"
            case workspaceId = "workspaceId"
        }
    }

    public struct DescribeWorkspaceAuthenticationRequest: AWSEncodableShape {
        /// The ID of the workspace to return authentication information about.
        public let workspaceId: String

        @inlinable
        public init(workspaceId: String) {
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeWorkspaceAuthenticationResponse: AWSDecodableShape {
        /// A structure containing information about the authentication methods used in the workspace.
        public let authentication: AuthenticationDescription

        @inlinable
        public init(authentication: AuthenticationDescription) {
            self.authentication = authentication
        }

        private enum CodingKeys: String, CodingKey {
            case authentication = "authentication"
        }
    }

    public struct DescribeWorkspaceConfigurationRequest: AWSEncodableShape {
        /// The ID of the workspace to get configuration information for.
        public let workspaceId: String

        @inlinable
        public init(workspaceId: String) {
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeWorkspaceConfigurationResponse: AWSDecodableShape {
        /// The configuration string for the workspace that you requested. For more information about the format and configuration options available, see Working in your Grafana workspace.
        public let configuration: String
        /// The supported Grafana version for the workspace.
        public let grafanaVersion: String?

        @inlinable
        public init(configuration: String, grafanaVersion: String? = nil) {
            self.configuration = configuration
            self.grafanaVersion = grafanaVersion
        }

        private enum CodingKeys: String, CodingKey {
            case configuration = "configuration"
            case grafanaVersion = "grafanaVersion"
        }
    }

    public struct DescribeWorkspaceRequest: AWSEncodableShape {
        /// The ID of the workspace to display information about.
        public let workspaceId: String

        @inlinable
        public init(workspaceId: String) {
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DescribeWorkspaceResponse: AWSDecodableShape {
        /// A structure containing information about the workspace.
        public let workspace: WorkspaceDescription

        @inlinable
        public init(workspace: WorkspaceDescription) {
            self.workspace = workspace
        }

        private enum CodingKeys: String, CodingKey {
            case workspace = "workspace"
        }
    }

    public struct DisassociateLicenseRequest: AWSEncodableShape {
        /// The type of license to remove from the workspace.
        public let licenseType: LicenseType
        /// The ID of the workspace to remove the Grafana Enterprise license from.
        public let workspaceId: String

        @inlinable
        public init(licenseType: LicenseType, workspaceId: String) {
            self.licenseType = licenseType
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.licenseType, key: "licenseType")
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct DisassociateLicenseResponse: AWSDecodableShape {
        /// A structure containing information about the workspace.
        public let workspace: WorkspaceDescription

        @inlinable
        public init(workspace: WorkspaceDescription) {
            self.workspace = workspace
        }

        private enum CodingKeys: String, CodingKey {
            case workspace = "workspace"
        }
    }

    public struct InternalServerException: AWSErrorShape {
        /// A description of the error.
        public let message: String
        /// How long to wait before you retry this operation.
        public let retryAfterSeconds: Int?

        @inlinable
        public init(message: String, retryAfterSeconds: Int? = nil) {
            self.message = message
            self.retryAfterSeconds = retryAfterSeconds
        }

        public init(from decoder: Decoder) throws {
            let response = decoder.userInfo[.awsResponse]! as! ResponseDecodingContainer
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.message = try container.decode(String.self, forKey: .message)
            self.retryAfterSeconds = try response.decodeHeaderIfPresent(Int.self, key: "Retry-After")
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
        }
    }

    public struct ListPermissionsRequest: AWSEncodableShape {
        /// (Optional) Limits the results to only the group that matches this ID.
        public let groupId: String?
        /// The maximum number of results to include in the response.
        public let maxResults: Int?
        /// The token to use when requesting the next set of results. You received this token from a previous ListPermissions operation.
        public let nextToken: String?
        /// (Optional) Limits the results to only the user that matches this ID.
        public let userId: String?
        /// (Optional) If you specify SSO_USER, then only the permissions of IAM Identity Center users are returned. If you specify SSO_GROUP, only the permissions of IAM Identity Center groups are returned.
        public let userType: UserType?
        /// The ID of the workspace to list permissions for. This parameter is required.
        public let workspaceId: String

        @inlinable
        public init(groupId: String? = nil, maxResults: Int? = nil, nextToken: String? = nil, userId: String? = nil, userType: UserType? = nil, workspaceId: String) {
            self.groupId = groupId
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.userId = userId
            self.userType = userType
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.groupId, key: "groupId")
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.userId, key: "userId")
            request.encodeQuery(self.userType, key: "userType")
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.groupId, name: "groupId", parent: name, max: 47)
            try self.validate(self.groupId, name: "groupId", parent: name, min: 1)
            try self.validate(self.userId, name: "userId", parent: name, max: 47)
            try self.validate(self.userId, name: "userId", parent: name, min: 1)
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListPermissionsResponse: AWSDecodableShape {
        /// The token to use in a subsequent ListPermissions operation to return the next set of results.
        public let nextToken: String?
        /// The permissions returned by the operation.
        public let permissions: [PermissionEntry]

        @inlinable
        public init(nextToken: String? = nil, permissions: [PermissionEntry]) {
            self.nextToken = nextToken
            self.permissions = permissions
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case permissions = "permissions"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The ARN of the resource the list of tags are associated with.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// The list of tags that are associated with the resource.
        public let tags: [String: String]?

        @inlinable
        public init(tags: [String: String]? = nil) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct ListVersionsRequest: AWSEncodableShape {
        /// The maximum number of results to include in the response.
        public let maxResults: Int?
        /// The token to use when requesting the next set of results. You receive this token from a previous ListVersions operation.
        public let nextToken: String?
        /// The ID of the workspace to list the available upgrade versions. If not included,  lists all versions of Grafana that are supported for  CreateWorkspace.
        public let workspaceId: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, workspaceId: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodeQuery(self.workspaceId, key: "workspace-id")
        }

        public func validate(name: String) throws {
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListVersionsResponse: AWSDecodableShape {
        /// The Grafana versions available to create. If a workspace ID is included in the  request, the Grafana versions to which this workspace can be upgraded.
        public let grafanaVersions: [String]?
        /// The token to use in a subsequent ListVersions operation to return the next set of results.
        public let nextToken: String?

        @inlinable
        public init(grafanaVersions: [String]? = nil, nextToken: String? = nil) {
            self.grafanaVersions = grafanaVersions
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case grafanaVersions = "grafanaVersions"
            case nextToken = "nextToken"
        }
    }

    public struct ListWorkspaceServiceAccountTokensRequest: AWSEncodableShape {
        /// The maximum number of tokens to include in the results.
        public let maxResults: Int?
        /// The token for the next set of service accounts to return. (You receive this token from a previous ListWorkspaceServiceAccountTokens operation.)
        public let nextToken: String?
        /// The ID of the service account for which to return tokens.
        public let serviceAccountId: String
        /// The ID of the workspace for which to return tokens.
        public let workspaceId: String

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, serviceAccountId: String, workspaceId: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.serviceAccountId = serviceAccountId
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodePath(self.serviceAccountId, key: "serviceAccountId")
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListWorkspaceServiceAccountTokensResponse: AWSDecodableShape {
        /// The token to use when requesting the next set of service accounts.
        public let nextToken: String?
        /// The ID of the service account where the tokens reside.
        public let serviceAccountId: String
        /// An array of structures containing information about the tokens.
        public let serviceAccountTokens: [ServiceAccountTokenSummary]
        /// The ID of the workspace where the tokens reside.
        public let workspaceId: String

        @inlinable
        public init(nextToken: String? = nil, serviceAccountId: String, serviceAccountTokens: [ServiceAccountTokenSummary], workspaceId: String) {
            self.nextToken = nextToken
            self.serviceAccountId = serviceAccountId
            self.serviceAccountTokens = serviceAccountTokens
            self.workspaceId = workspaceId
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case serviceAccountId = "serviceAccountId"
            case serviceAccountTokens = "serviceAccountTokens"
            case workspaceId = "workspaceId"
        }
    }

    public struct ListWorkspaceServiceAccountsRequest: AWSEncodableShape {
        /// The maximum number of service accounts to include in the results.
        public let maxResults: Int?
        /// The token for the next set of service accounts to return. (You receive this token from a previous ListWorkspaceServiceAccounts operation.)
        public let nextToken: String?
        /// The workspace for which to list service accounts.
        public let workspaceId: String

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil, workspaceId: String) {
            self.maxResults = maxResults
            self.nextToken = nextToken
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListWorkspaceServiceAccountsResponse: AWSDecodableShape {
        /// The token to use when requesting the next set of service accounts.
        public let nextToken: String?
        /// An array of structures containing information about the service accounts.
        public let serviceAccounts: [ServiceAccountSummary]
        /// The workspace to which the service accounts are associated.
        public let workspaceId: String

        @inlinable
        public init(nextToken: String? = nil, serviceAccounts: [ServiceAccountSummary], workspaceId: String) {
            self.nextToken = nextToken
            self.serviceAccounts = serviceAccounts
            self.workspaceId = workspaceId
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case serviceAccounts = "serviceAccounts"
            case workspaceId = "workspaceId"
        }
    }

    public struct ListWorkspacesRequest: AWSEncodableShape {
        /// The maximum number of workspaces to include in the results.
        public let maxResults: Int?
        /// The token for the next set of workspaces to return. (You receive this token from a previous ListWorkspaces operation.)
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodeQuery(self.maxResults, key: "maxResults")
            request.encodeQuery(self.nextToken, key: "nextToken")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListWorkspacesResponse: AWSDecodableShape {
        /// The token to use when requesting the next set of workspaces.
        public let nextToken: String?
        /// An array of structures that contain some information about the workspaces in the account.
        public let workspaces: [WorkspaceSummary]

        @inlinable
        public init(nextToken: String? = nil, workspaces: [WorkspaceSummary]) {
            self.nextToken = nextToken
            self.workspaces = workspaces
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case workspaces = "workspaces"
        }
    }

    public struct NetworkAccessConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// An array of prefix list IDs. A prefix list is a list of CIDR ranges of IP addresses. The IP addresses specified are allowed to access your workspace. If the list is not included in the configuration (passed an empty array) then no IP addresses are  allowed to access the workspace. You create a prefix list using the Amazon VPC  console. Prefix list IDs have the format pl-1a2b3c4d . For more information about prefix lists, see Group CIDR blocks using managed prefix listsin the Amazon Virtual Private Cloud User Guide.
        public let prefixListIds: [String]
        /// An array of Amazon VPC endpoint IDs for the workspace. You can create VPC endpoints to your Amazon Managed Grafana workspace for access from within a VPC. If a NetworkAccessConfiguration is specified then only VPC endpoints specified here are allowed to access the workspace. If you pass in an empty array of strings, then no VPCs are allowed to access the workspace. VPC endpoint IDs have the format vpce-1a2b3c4d . For more information about creating an interface VPC endpoint, see Interface VPC endpoints in the Amazon Managed Grafana User Guide.  The only VPC endpoints that can be specified here are interface VPC endpoints for Grafana workspaces (using the com.amazonaws.[region].grafana-workspace service endpoint). Other VPC endpoints are ignored.
        public let vpceIds: [String]

        @inlinable
        public init(prefixListIds: [String], vpceIds: [String]) {
            self.prefixListIds = prefixListIds
            self.vpceIds = vpceIds
        }

        public func validate(name: String) throws {
            try self.prefixListIds.forEach {
                try validate($0, name: "prefixListIds[]", parent: name, max: 100)
                try validate($0, name: "prefixListIds[]", parent: name, min: 1)
            }
            try self.vpceIds.forEach {
                try validate($0, name: "vpceIds[]", parent: name, max: 100)
                try validate($0, name: "vpceIds[]", parent: name, min: 1)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case prefixListIds = "prefixListIds"
            case vpceIds = "vpceIds"
        }
    }

    public struct PermissionEntry: AWSDecodableShape {
        /// Specifies whether the user or group has the Admin, Editor, or Viewer role.
        public let role: Role
        /// A structure with the ID of the user or group with this role.
        public let user: User

        @inlinable
        public init(role: Role, user: User) {
            self.role = role
            self.user = user
        }

        private enum CodingKeys: String, CodingKey {
            case role = "role"
            case user = "user"
        }
    }

    public struct ResourceNotFoundException: AWSErrorShape {
        /// The value of a parameter in the request caused an error.
        public let message: String
        /// The ID of the resource that is associated with the error.
        public let resourceId: String
        /// The type of the resource that is associated with the error.
        public let resourceType: String

        @inlinable
        public init(message: String, resourceId: String, resourceType: String) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct RoleValues: AWSEncodableShape & AWSDecodableShape {
        /// A list of groups from the SAML assertion attribute to grant the Grafana Admin role to.
        public let admin: [String]?
        /// A list of groups from the SAML assertion attribute to grant the Grafana Editor role to.
        public let editor: [String]?

        @inlinable
        public init(admin: [String]? = nil, editor: [String]? = nil) {
            self.admin = admin
            self.editor = editor
        }

        public func validate(name: String) throws {
            try self.admin?.forEach {
                try validate($0, name: "admin[]", parent: name, max: 256)
                try validate($0, name: "admin[]", parent: name, min: 1)
            }
            try self.editor?.forEach {
                try validate($0, name: "editor[]", parent: name, max: 256)
                try validate($0, name: "editor[]", parent: name, min: 1)
            }
        }

        private enum CodingKeys: String, CodingKey {
            case admin = "admin"
            case editor = "editor"
        }
    }

    public struct SamlAuthentication: AWSDecodableShape {
        /// A structure containing details about how this workspace works with SAML.
        public let configuration: SamlConfiguration?
        /// Specifies whether the workspace's SAML configuration is complete.
        public let status: SamlConfigurationStatus

        @inlinable
        public init(configuration: SamlConfiguration? = nil, status: SamlConfigurationStatus) {
            self.configuration = configuration
            self.status = status
        }

        private enum CodingKeys: String, CodingKey {
            case configuration = "configuration"
            case status = "status"
        }
    }

    public struct SamlConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Lists which organizations defined in the SAML assertion are allowed to use the Amazon Managed Grafana workspace. If this is empty, all organizations in the assertion attribute have access.
        public let allowedOrganizations: [String]?
        /// A structure that defines which attributes in the SAML assertion are to be used to define information about the users authenticated by that IdP to use the workspace.
        public let assertionAttributes: AssertionAttributes?
        /// A structure containing the identity provider (IdP) metadata used to integrate the identity provider with this workspace.
        public let idpMetadata: IdpMetadata
        /// How long a sign-on session by a SAML user is valid, before the user has to sign on again.
        public let loginValidityDuration: Int?
        /// A structure containing arrays that map group names in the SAML assertion to the Grafana Admin and Editor roles in the workspace.
        public let roleValues: RoleValues?

        @inlinable
        public init(allowedOrganizations: [String]? = nil, assertionAttributes: AssertionAttributes? = nil, idpMetadata: IdpMetadata, loginValidityDuration: Int? = nil, roleValues: RoleValues? = nil) {
            self.allowedOrganizations = allowedOrganizations
            self.assertionAttributes = assertionAttributes
            self.idpMetadata = idpMetadata
            self.loginValidityDuration = loginValidityDuration
            self.roleValues = roleValues
        }

        public func validate(name: String) throws {
            try self.allowedOrganizations?.forEach {
                try validate($0, name: "allowedOrganizations[]", parent: name, max: 256)
                try validate($0, name: "allowedOrganizations[]", parent: name, min: 1)
            }
            try self.assertionAttributes?.validate(name: "\(name).assertionAttributes")
            try self.idpMetadata.validate(name: "\(name).idpMetadata")
            try self.roleValues?.validate(name: "\(name).roleValues")
        }

        private enum CodingKeys: String, CodingKey {
            case allowedOrganizations = "allowedOrganizations"
            case assertionAttributes = "assertionAttributes"
            case idpMetadata = "idpMetadata"
            case loginValidityDuration = "loginValidityDuration"
            case roleValues = "roleValues"
        }
    }

    public struct ServiceAccountSummary: AWSDecodableShape {
        /// The role of the service account, which sets the permission level used when calling Grafana APIs.
        public let grafanaRole: Role
        /// The unique ID of the service account.
        public let id: String
        /// Returns true if the service account is disabled. Service accounts can be disabled and enabled in the Amazon Managed Grafana console.
        public let isDisabled: String
        /// The name of the service account.
        public let name: String

        @inlinable
        public init(grafanaRole: Role, id: String, isDisabled: String, name: String) {
            self.grafanaRole = grafanaRole
            self.id = id
            self.isDisabled = isDisabled
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case grafanaRole = "grafanaRole"
            case id = "id"
            case isDisabled = "isDisabled"
            case name = "name"
        }
    }

    public struct ServiceAccountTokenSummary: AWSDecodableShape {
        /// When the service account token was created.
        public let createdAt: Date
        /// When the service account token will expire.
        public let expiresAt: Date
        /// The unique ID of the service account token.
        public let id: String
        /// The last time the token was used to authorize a Grafana HTTP API.
        public let lastUsedAt: Date?
        /// The name of the service account token.
        public let name: String

        @inlinable
        public init(createdAt: Date, expiresAt: Date, id: String, lastUsedAt: Date? = nil, name: String) {
            self.createdAt = createdAt
            self.expiresAt = expiresAt
            self.id = id
            self.lastUsedAt = lastUsedAt
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case createdAt = "createdAt"
            case expiresAt = "expiresAt"
            case id = "id"
            case lastUsedAt = "lastUsedAt"
            case name = "name"
        }
    }

    public struct ServiceAccountTokenSummaryWithKey: AWSDecodableShape {
        /// The unique ID of the service account token.
        public let id: String
        /// The key for the service account token. Used when making calls to the Grafana HTTP  APIs to authenticate and authorize the requests.
        public let key: String
        /// The name of the service account token.
        public let name: String

        @inlinable
        public init(id: String, key: String, name: String) {
            self.id = id
            self.key = key
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case id = "id"
            case key = "key"
            case name = "name"
        }
    }

    public struct ServiceQuotaExceededException: AWSErrorShape {
        /// A description of the error.
        public let message: String
        /// The ID of the service quota that was exceeded.
        public let quotaCode: String
        /// The ID of the resource that is associated with the error.
        public let resourceId: String
        /// The type of the resource that is associated with the error.
        public let resourceType: String
        /// The value of a parameter in the request caused an error.
        public let serviceCode: String

        @inlinable
        public init(message: String, quotaCode: String, resourceId: String, resourceType: String, serviceCode: String) {
            self.message = message
            self.quotaCode = quotaCode
            self.resourceId = resourceId
            self.resourceType = resourceType
            self.serviceCode = serviceCode
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case quotaCode = "quotaCode"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
            case serviceCode = "serviceCode"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The ARN of the resource the tag is associated with.
        public let resourceArn: String
        /// The list of tag keys and values to associate with the resource. You can associate tag keys only, tags (key and values) only or a combination of tag keys and tags.
        public let tags: [String: String]

        @inlinable
        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            try container.encode(self.tags, forKey: .tags)
        }

        public func validate(name: String) throws {
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct ThrottlingException: AWSErrorShape {
        /// A description of the error.
        public let message: String
        /// The ID of the service quota that was exceeded.
        public let quotaCode: String?
        /// The value of a parameter in the request caused an error.
        public let retryAfterSeconds: Int?
        /// The ID of the service that is associated with the error.
        public let serviceCode: String?

        @inlinable
        public init(message: String, quotaCode: String? = nil, retryAfterSeconds: Int? = nil, serviceCode: String? = nil) {
            self.message = message
            self.quotaCode = quotaCode
            self.retryAfterSeconds = retryAfterSeconds
            self.serviceCode = serviceCode
        }

        public init(from decoder: Decoder) throws {
            let response = decoder.userInfo[.awsResponse]! as! ResponseDecodingContainer
            let container = try decoder.container(keyedBy: CodingKeys.self)
            self.message = try container.decode(String.self, forKey: .message)
            self.quotaCode = try container.decodeIfPresent(String.self, forKey: .quotaCode)
            self.retryAfterSeconds = try response.decodeHeaderIfPresent(Int.self, key: "Retry-After")
            self.serviceCode = try container.decodeIfPresent(String.self, forKey: .serviceCode)
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case quotaCode = "quotaCode"
            case serviceCode = "serviceCode"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The ARN of the resource the tag association is removed from.
        public let resourceArn: String
        /// The key values of the tag to be removed from the resource.
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            request.encodeQuery(self.tagKeys, key: "tagKeys")
        }

        public func validate(name: String) throws {
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
            }
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateError: AWSDecodableShape {
        /// Specifies which permission update caused the error.
        public let causedBy: UpdateInstruction
        /// The error code.
        public let code: Int
        /// The message for this error.
        public let message: String

        @inlinable
        public init(causedBy: UpdateInstruction, code: Int, message: String) {
            self.causedBy = causedBy
            self.code = code
            self.message = message
        }

        private enum CodingKeys: String, CodingKey {
            case causedBy = "causedBy"
            case code = "code"
            case message = "message"
        }
    }

    public struct UpdateInstruction: AWSEncodableShape & AWSDecodableShape {
        /// Specifies whether this update is to add or revoke role permissions.
        public let action: UpdateAction
        /// The role to add or revoke for the user or the group specified in users.
        public let role: Role
        /// A structure that specifies the user or group to add or revoke the role for.
        public let users: [User]

        @inlinable
        public init(action: UpdateAction, role: Role, users: [User]) {
            self.action = action
            self.role = role
            self.users = users
        }

        public func validate(name: String) throws {
            try self.users.forEach {
                try $0.validate(name: "\(name).users[]")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case action = "action"
            case role = "role"
            case users = "users"
        }
    }

    public struct UpdatePermissionsRequest: AWSEncodableShape {
        /// An array of structures that contain the permission updates to make.
        public let updateInstructionBatch: [UpdateInstruction]
        /// The ID of the workspace to update.
        public let workspaceId: String

        @inlinable
        public init(updateInstructionBatch: [UpdateInstruction], workspaceId: String) {
            self.updateInstructionBatch = updateInstructionBatch
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.updateInstructionBatch, forKey: .updateInstructionBatch)
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.updateInstructionBatch.forEach {
                try $0.validate(name: "\(name).updateInstructionBatch[]")
            }
            try self.validate(self.updateInstructionBatch, name: "updateInstructionBatch", parent: name, max: 20)
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: String, CodingKey {
            case updateInstructionBatch = "updateInstructionBatch"
        }
    }

    public struct UpdatePermissionsResponse: AWSDecodableShape {
        /// An array of structures that contain the errors from the operation, if any.
        public let errors: [UpdateError]

        @inlinable
        public init(errors: [UpdateError]) {
            self.errors = errors
        }

        private enum CodingKeys: String, CodingKey {
            case errors = "errors"
        }
    }

    public struct UpdateWorkspaceAuthenticationRequest: AWSEncodableShape {
        /// Specifies whether this workspace uses SAML 2.0, IAM Identity Center, or both to authenticate users for using the Grafana console within a workspace. For more information, see User authentication in Amazon Managed Grafana.
        public let authenticationProviders: [AuthenticationProviderTypes]
        /// If the workspace uses SAML, use this structure to map SAML assertion attributes to workspace user information and define which groups in the assertion attribute are to have the Admin and Editor roles in the workspace.
        public let samlConfiguration: SamlConfiguration?
        /// The ID of the workspace to update the authentication for.
        public let workspaceId: String

        @inlinable
        public init(authenticationProviders: [AuthenticationProviderTypes], samlConfiguration: SamlConfiguration? = nil, workspaceId: String) {
            self.authenticationProviders = authenticationProviders
            self.samlConfiguration = samlConfiguration
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.authenticationProviders, forKey: .authenticationProviders)
            try container.encodeIfPresent(self.samlConfiguration, forKey: .samlConfiguration)
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.samlConfiguration?.validate(name: "\(name).samlConfiguration")
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: String, CodingKey {
            case authenticationProviders = "authenticationProviders"
            case samlConfiguration = "samlConfiguration"
        }
    }

    public struct UpdateWorkspaceAuthenticationResponse: AWSDecodableShape {
        /// A structure that describes the user authentication for this workspace after the update is made.
        public let authentication: AuthenticationDescription

        @inlinable
        public init(authentication: AuthenticationDescription) {
            self.authentication = authentication
        }

        private enum CodingKeys: String, CodingKey {
            case authentication = "authentication"
        }
    }

    public struct UpdateWorkspaceConfigurationRequest: AWSEncodableShape {
        /// The new configuration string for the workspace. For more information about the format and configuration options available, see Working in your Grafana workspace.
        public let configuration: String
        /// Specifies the version of Grafana to support in the workspace. If not specified,  keeps the current version of the workspace. Can only be used to upgrade (for example, from 8.4 to 9.4), not downgrade (for example, from 9.4 to 8.4). To know what versions are available to upgrade to for a specific workspace, see  the ListVersions operation.
        public let grafanaVersion: String?
        /// The ID of the workspace to update.
        public let workspaceId: String

        @inlinable
        public init(configuration: String, grafanaVersion: String? = nil, workspaceId: String) {
            self.configuration = configuration
            self.grafanaVersion = grafanaVersion
            self.workspaceId = workspaceId
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encode(self.configuration, forKey: .configuration)
            try container.encodeIfPresent(self.grafanaVersion, forKey: .grafanaVersion)
            request.encodePath(self.workspaceId, key: "workspaceId")
        }

        public func validate(name: String) throws {
            try self.validate(self.configuration, name: "configuration", parent: name, max: 65536)
            try self.validate(self.configuration, name: "configuration", parent: name, min: 2)
            try self.validate(self.grafanaVersion, name: "grafanaVersion", parent: name, max: 255)
            try self.validate(self.grafanaVersion, name: "grafanaVersion", parent: name, min: 1)
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
        }

        private enum CodingKeys: String, CodingKey {
            case configuration = "configuration"
            case grafanaVersion = "grafanaVersion"
        }
    }

    public struct UpdateWorkspaceConfigurationResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateWorkspaceRequest: AWSEncodableShape {
        /// Specifies whether the workspace can access Amazon Web Services resources in this Amazon Web Services account only, or whether it can also access Amazon Web Services resources in other accounts in the same organization. If you specify ORGANIZATION, you must specify which organizational units the workspace can access in the workspaceOrganizationalUnits parameter.
        public let accountAccessType: AccountAccessType?
        /// The configuration settings for network access to your workspace. When this is configured, only listed IP addresses and VPC endpoints will be able to access your workspace. Standard Grafana authentication and authorization will still be required. If this is not configured, or is removed, then all IP addresses and VPC endpoints will be allowed. Standard Grafana authentication and authorization will still be required.
        public let networkAccessControl: NetworkAccessConfiguration?
        /// The name of an IAM role that already exists to use to access resources through Organizations. This can only be used with a workspace that has the  permissionType set to CUSTOMER_MANAGED.
        public let organizationRoleName: String?
        /// Use this parameter if you want to change a workspace from SERVICE_MANAGED to CUSTOMER_MANAGED. This allows you to manage the permissions that the  workspace uses to access datasources and notification channels. If the workspace is in a member Amazon Web Services account of an organization, and that account is not a delegated administrator account, and you want the workspace to access data sources in  other Amazon Web Services accounts in the organization, you must choose  CUSTOMER_MANAGED. If you specify this as CUSTOMER_MANAGED, you must also specify a  workspaceRoleArn that the workspace will use for accessing Amazon Web Services resources. For more information on the role and permissions needed, see Amazon Managed Grafana permissions and policies for Amazon Web Services data sources  and notification channels   Do not use this to convert a CUSTOMER_MANAGED workspace to SERVICE_MANAGED. Do not include this  parameter if you want to leave the workspace as SERVICE_MANAGED. You can convert a CUSTOMER_MANAGED workspace to  SERVICE_MANAGED using the Amazon Managed Grafana console. For more  information, see Managing permissions for data sources and notification channels.
        public let permissionType: PermissionType?
        /// Whether to remove the network access configuration from the workspace. Setting this to true and providing a networkAccessControl to set will return an error. If you remove this configuration by setting this to true, then all IP addresses and VPC endpoints will be allowed. Standard Grafana authentication and authorization will still be required.
        public let removeNetworkAccessConfiguration: Bool?
        /// Whether to remove the VPC configuration from the workspace. Setting this to true and providing a vpcConfiguration to set will return an error.
        public let removeVpcConfiguration: Bool?
        /// The name of the CloudFormation stack set to use to generate IAM roles to be used for this workspace.
        public let stackSetName: String?
        /// The configuration settings for an Amazon VPC that contains data sources for your Grafana workspace to connect to.
        public let vpcConfiguration: VpcConfiguration?
        /// This parameter is for internal use only, and should not be used.
        public let workspaceDataSources: [DataSourceType]?
        /// A description for the workspace. This is used only to help you identify this workspace.
        public let workspaceDescription: String?
        /// The ID of the workspace to update.
        public let workspaceId: String
        /// A new name for the workspace to update.
        public let workspaceName: String?
        /// Specify the Amazon Web Services notification channels that you plan to use in this workspace. Specifying these data sources here enables Amazon Managed Grafana to create IAM roles and permissions that allow Amazon Managed Grafana to use these channels.
        public let workspaceNotificationDestinations: [NotificationDestinationType]?
        /// Specifies the organizational units that this workspace is allowed to use data sources from, if this workspace is in an account that is part of an organization.
        public let workspaceOrganizationalUnits: [String]?
        /// Specifies an IAM role that grants permissions to Amazon Web Services resources that the workspace accesses, such as data sources and notification channels. If this workspace has permissionType CUSTOMER_MANAGED, then this role is required.
        public let workspaceRoleArn: String?

        @inlinable
        public init(accountAccessType: AccountAccessType? = nil, networkAccessControl: NetworkAccessConfiguration? = nil, organizationRoleName: String? = nil, permissionType: PermissionType? = nil, removeNetworkAccessConfiguration: Bool? = nil, removeVpcConfiguration: Bool? = nil, stackSetName: String? = nil, vpcConfiguration: VpcConfiguration? = nil, workspaceDataSources: [DataSourceType]? = nil, workspaceDescription: String? = nil, workspaceId: String, workspaceName: String? = nil, workspaceNotificationDestinations: [NotificationDestinationType]? = nil, workspaceOrganizationalUnits: [String]? = nil, workspaceRoleArn: String? = nil) {
            self.accountAccessType = accountAccessType
            self.networkAccessControl = networkAccessControl
            self.organizationRoleName = organizationRoleName
            self.permissionType = permissionType
            self.removeNetworkAccessConfiguration = removeNetworkAccessConfiguration
            self.removeVpcConfiguration = removeVpcConfiguration
            self.stackSetName = stackSetName
            self.vpcConfiguration = vpcConfiguration
            self.workspaceDataSources = workspaceDataSources
            self.workspaceDescription = workspaceDescription
            self.workspaceId = workspaceId
            self.workspaceName = workspaceName
            self.workspaceNotificationDestinations = workspaceNotificationDestinations
            self.workspaceOrganizationalUnits = workspaceOrganizationalUnits
            self.workspaceRoleArn = workspaceRoleArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            try container.encodeIfPresent(self.accountAccessType, forKey: .accountAccessType)
            try container.encodeIfPresent(self.networkAccessControl, forKey: .networkAccessControl)
            try container.encodeIfPresent(self.organizationRoleName, forKey: .organizationRoleName)
            try container.encodeIfPresent(self.permissionType, forKey: .permissionType)
            try container.encodeIfPresent(self.removeNetworkAccessConfiguration, forKey: .removeNetworkAccessConfiguration)
            try container.encodeIfPresent(self.removeVpcConfiguration, forKey: .removeVpcConfiguration)
            try container.encodeIfPresent(self.stackSetName, forKey: .stackSetName)
            try container.encodeIfPresent(self.vpcConfiguration, forKey: .vpcConfiguration)
            try container.encodeIfPresent(self.workspaceDataSources, forKey: .workspaceDataSources)
            try container.encodeIfPresent(self.workspaceDescription, forKey: .workspaceDescription)
            request.encodePath(self.workspaceId, key: "workspaceId")
            try container.encodeIfPresent(self.workspaceName, forKey: .workspaceName)
            try container.encodeIfPresent(self.workspaceNotificationDestinations, forKey: .workspaceNotificationDestinations)
            try container.encodeIfPresent(self.workspaceOrganizationalUnits, forKey: .workspaceOrganizationalUnits)
            try container.encodeIfPresent(self.workspaceRoleArn, forKey: .workspaceRoleArn)
        }

        public func validate(name: String) throws {
            try self.networkAccessControl?.validate(name: "\(name).networkAccessControl")
            try self.validate(self.organizationRoleName, name: "organizationRoleName", parent: name, max: 2048)
            try self.validate(self.organizationRoleName, name: "organizationRoleName", parent: name, min: 1)
            try self.vpcConfiguration?.validate(name: "\(name).vpcConfiguration")
            try self.validate(self.workspaceDescription, name: "workspaceDescription", parent: name, max: 2048)
            try self.validate(self.workspaceId, name: "workspaceId", parent: name, pattern: "^g-[0-9a-f]{10}$")
            try self.validate(self.workspaceName, name: "workspaceName", parent: name, pattern: "^[a-zA-Z0-9-._~]{1,255}$")
            try self.validate(self.workspaceRoleArn, name: "workspaceRoleArn", parent: name, max: 2048)
            try self.validate(self.workspaceRoleArn, name: "workspaceRoleArn", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case accountAccessType = "accountAccessType"
            case networkAccessControl = "networkAccessControl"
            case organizationRoleName = "organizationRoleName"
            case permissionType = "permissionType"
            case removeNetworkAccessConfiguration = "removeNetworkAccessConfiguration"
            case removeVpcConfiguration = "removeVpcConfiguration"
            case stackSetName = "stackSetName"
            case vpcConfiguration = "vpcConfiguration"
            case workspaceDataSources = "workspaceDataSources"
            case workspaceDescription = "workspaceDescription"
            case workspaceName = "workspaceName"
            case workspaceNotificationDestinations = "workspaceNotificationDestinations"
            case workspaceOrganizationalUnits = "workspaceOrganizationalUnits"
            case workspaceRoleArn = "workspaceRoleArn"
        }
    }

    public struct UpdateWorkspaceResponse: AWSDecodableShape {
        /// A structure containing data about the workspace that was created.
        public let workspace: WorkspaceDescription

        @inlinable
        public init(workspace: WorkspaceDescription) {
            self.workspace = workspace
        }

        private enum CodingKeys: String, CodingKey {
            case workspace = "workspace"
        }
    }

    public struct User: AWSEncodableShape & AWSDecodableShape {
        /// The ID of the user or group. Pattern: ^([0-9a-fA-F]{10}-|)[A-Fa-f0-9]{8}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{4}-[A-Fa-f0-9]{12}$
        public let id: String
        /// Specifies whether this is a single user or a group.
        public let type: UserType

        @inlinable
        public init(id: String, type: UserType) {
            self.id = id
            self.type = type
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, max: 47)
            try self.validate(self.id, name: "id", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case id = "id"
            case type = "type"
        }
    }

    public struct ValidationException: AWSErrorShape {
        /// A list of fields that might be associated with the error.
        public let fieldList: [ValidationExceptionField]?
        /// A description of the error.
        public let message: String
        /// The reason that the operation failed.
        public let reason: ValidationExceptionReason

        @inlinable
        public init(fieldList: [ValidationExceptionField]? = nil, message: String, reason: ValidationExceptionReason) {
            self.fieldList = fieldList
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case fieldList = "fieldList"
            case message = "message"
            case reason = "reason"
        }
    }

    public struct ValidationExceptionField: AWSDecodableShape {
        /// A message describing why this field couldn't be validated.
        public let message: String
        /// The name of the field that caused the validation error.
        public let name: String

        @inlinable
        public init(message: String, name: String) {
            self.message = message
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case name = "name"
        }
    }

    public struct VpcConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// The list of Amazon EC2 security group IDs attached to the Amazon VPC for your Grafana workspace to connect. Duplicates not allowed.
        public let securityGroupIds: [String]
        /// The list of Amazon EC2 subnet IDs created in the Amazon VPC for your Grafana workspace to connect. Duplicates not allowed.
        public let subnetIds: [String]

        @inlinable
        public init(securityGroupIds: [String], subnetIds: [String]) {
            self.securityGroupIds = securityGroupIds
            self.subnetIds = subnetIds
        }

        public func validate(name: String) throws {
            try self.securityGroupIds.forEach {
                try validate($0, name: "securityGroupIds[]", parent: name, max: 255)
            }
            try self.validate(self.securityGroupIds, name: "securityGroupIds", parent: name, max: 5)
            try self.validate(self.securityGroupIds, name: "securityGroupIds", parent: name, min: 1)
            try self.subnetIds.forEach {
                try validate($0, name: "subnetIds[]", parent: name, max: 255)
            }
            try self.validate(self.subnetIds, name: "subnetIds", parent: name, max: 6)
            try self.validate(self.subnetIds, name: "subnetIds", parent: name, min: 2)
        }

        private enum CodingKeys: String, CodingKey {
            case securityGroupIds = "securityGroupIds"
            case subnetIds = "subnetIds"
        }
    }

    public struct WorkspaceDescription: AWSDecodableShape {
        /// Specifies whether the workspace can access Amazon Web Services resources in this Amazon Web Services account only, or whether it can also access Amazon Web Services resources in other accounts in the same organization. If this is ORGANIZATION, the workspaceOrganizationalUnits parameter specifies which organizational units the workspace can access.
        public let accountAccessType: AccountAccessType?
        /// A structure that describes whether the workspace uses SAML, IAM Identity Center, or both methods for user authentication.
        public let authentication: AuthenticationSummary
        /// The date that the workspace was created.
        public let created: Date
        /// Specifies the Amazon Web Services data sources that have been configured to have IAM roles and permissions created to allow Amazon Managed Grafana to read data from these sources. This list is only used when the workspace was created through the Amazon Web Services console, and the permissionType is SERVICE_MANAGED.
        public let dataSources: [DataSourceType]
        /// The user-defined description of the workspace.
        public let description: String?
        /// The URL that users can use to access the Grafana console in the workspace.
        public let endpoint: String
        /// Specifies whether this workspace has already fully used its free trial for Grafana Enterprise.  Amazon Managed Grafana workspaces no longer support Grafana Enterprise free trials.
        public let freeTrialConsumed: Bool?
        /// If this workspace is currently in the free trial period for Grafana Enterprise, this value specifies when that free trial ends.  Amazon Managed Grafana workspaces no longer support Grafana Enterprise free trials.
        public let freeTrialExpiration: Date?
        /// The token that ties this workspace to a Grafana Labs account. For more information,  see Link your account with Grafana Labs.
        public let grafanaToken: String?
        /// The version of Grafana supported in this workspace.
        public let grafanaVersion: String
        /// The unique ID of this workspace.
        public let id: String
        /// If this workspace has a full Grafana Enterprise license purchased through  Amazon Web Services Marketplace, this specifies when the license ends and will need to be renewed. Purchasing the Enterprise plugins option  through Amazon Managed Grafana does not have an expiration. It is valid until the  license is removed.
        public let licenseExpiration: Date?
        /// Specifies whether this workspace has a full Grafana Enterprise license.  Amazon Managed Grafana workspaces no longer support Grafana Enterprise free trials.
        public let licenseType: LicenseType?
        /// The most recent date that the workspace was modified.
        public let modified: Date
        /// The name of the workspace.
        public let name: String?
        /// The configuration settings for network access to your workspace.
        public let networkAccessControl: NetworkAccessConfiguration?
        /// The Amazon Web Services notification channels that Amazon Managed Grafana can automatically create IAM roles and permissions for, to allow Amazon Managed Grafana to use these channels.
        public let notificationDestinations: [NotificationDestinationType]?
        /// Specifies the organizational units that this workspace is allowed to use data sources from, if this workspace is in an account that is part of an organization.
        public let organizationalUnits: [String]?
        /// The name of the IAM role that is used to access resources through Organizations.
        public let organizationRoleName: String?
        /// If this is SERVICE_MANAGED, and the workplace was created through the  Amazon Managed Grafana console, then Amazon Managed Grafana automatically creates the IAM roles and provisions the permissions that the workspace needs to use Amazon Web Services data sources and notification channels. If this is CUSTOMER_MANAGED, you must manage those roles and permissions yourself. If you are working with a workspace in a member account of an organization and that account is not a delegated administrator account, and you want the workspace to access data sources in other Amazon Web Services accounts in the organization, this parameter must be set to CUSTOMER_MANAGED. For more information about converting between customer and service managed, see Managing permissions for data sources and notification channels. For more information about the roles and permissions that must be managed for customer managed  workspaces, see Amazon Managed Grafana permissions and policies for Amazon Web Services data sources and notification channels
        public let permissionType: PermissionType?
        /// The name of the CloudFormation stack set that is used to generate IAM roles to be used for this workspace.
        public let stackSetName: String?
        /// The current status of the workspace.
        public let status: WorkspaceStatus
        /// The list of tags associated with the workspace.
        public let tags: [String: String]?
        /// The configuration for connecting to data sources in a private VPC (Amazon Virtual Private Cloud).
        public let vpcConfiguration: VpcConfiguration?
        /// The IAM role that grants permissions to the Amazon Web Services resources that the workspace will view data from. This role must already exist.
        public let workspaceRoleArn: String?

        @inlinable
        public init(accountAccessType: AccountAccessType? = nil, authentication: AuthenticationSummary, created: Date, dataSources: [DataSourceType], description: String? = nil, endpoint: String, freeTrialConsumed: Bool? = nil, freeTrialExpiration: Date? = nil, grafanaToken: String? = nil, grafanaVersion: String, id: String, licenseExpiration: Date? = nil, licenseType: LicenseType? = nil, modified: Date, name: String? = nil, networkAccessControl: NetworkAccessConfiguration? = nil, notificationDestinations: [NotificationDestinationType]? = nil, organizationalUnits: [String]? = nil, organizationRoleName: String? = nil, permissionType: PermissionType? = nil, stackSetName: String? = nil, status: WorkspaceStatus, tags: [String: String]? = nil, vpcConfiguration: VpcConfiguration? = nil, workspaceRoleArn: String? = nil) {
            self.accountAccessType = accountAccessType
            self.authentication = authentication
            self.created = created
            self.dataSources = dataSources
            self.description = description
            self.endpoint = endpoint
            self.freeTrialConsumed = freeTrialConsumed
            self.freeTrialExpiration = freeTrialExpiration
            self.grafanaToken = grafanaToken
            self.grafanaVersion = grafanaVersion
            self.id = id
            self.licenseExpiration = licenseExpiration
            self.licenseType = licenseType
            self.modified = modified
            self.name = name
            self.networkAccessControl = networkAccessControl
            self.notificationDestinations = notificationDestinations
            self.organizationalUnits = organizationalUnits
            self.organizationRoleName = organizationRoleName
            self.permissionType = permissionType
            self.stackSetName = stackSetName
            self.status = status
            self.tags = tags
            self.vpcConfiguration = vpcConfiguration
            self.workspaceRoleArn = workspaceRoleArn
        }

        private enum CodingKeys: String, CodingKey {
            case accountAccessType = "accountAccessType"
            case authentication = "authentication"
            case created = "created"
            case dataSources = "dataSources"
            case description = "description"
            case endpoint = "endpoint"
            case freeTrialConsumed = "freeTrialConsumed"
            case freeTrialExpiration = "freeTrialExpiration"
            case grafanaToken = "grafanaToken"
            case grafanaVersion = "grafanaVersion"
            case id = "id"
            case licenseExpiration = "licenseExpiration"
            case licenseType = "licenseType"
            case modified = "modified"
            case name = "name"
            case networkAccessControl = "networkAccessControl"
            case notificationDestinations = "notificationDestinations"
            case organizationalUnits = "organizationalUnits"
            case organizationRoleName = "organizationRoleName"
            case permissionType = "permissionType"
            case stackSetName = "stackSetName"
            case status = "status"
            case tags = "tags"
            case vpcConfiguration = "vpcConfiguration"
            case workspaceRoleArn = "workspaceRoleArn"
        }
    }

    public struct WorkspaceSummary: AWSDecodableShape {
        /// A structure containing information about the authentication methods used in the workspace.
        public let authentication: AuthenticationSummary
        /// The date that the workspace was created.
        public let created: Date
        /// The customer-entered description of the workspace.
        public let description: String?
        /// The URL endpoint to use to access the Grafana console in the workspace.
        public let endpoint: String
        /// The token that ties this workspace to a Grafana Labs account. For more information,  see Link your account with Grafana Labs.
        public let grafanaToken: String?
        /// The Grafana version that the workspace is running.
        public let grafanaVersion: String
        /// The unique ID of the workspace.
        public let id: String
        /// Specifies whether this workspace has a full Grafana Enterprise license.  Amazon Managed Grafana workspaces no longer support Grafana Enterprise free trials.
        public let licenseType: LicenseType?
        /// The most recent date that the workspace was modified.
        public let modified: Date
        /// The name of the workspace.
        public let name: String?
        /// The Amazon Web Services notification channels that Amazon Managed Grafana can automatically create IAM roles and permissions for, which allows Amazon Managed Grafana to use these channels.
        public let notificationDestinations: [NotificationDestinationType]?
        /// The current status of the workspace.
        public let status: WorkspaceStatus
        /// The list of tags associated with the workspace.
        public let tags: [String: String]?

        @inlinable
        public init(authentication: AuthenticationSummary, created: Date, description: String? = nil, endpoint: String, grafanaToken: String? = nil, grafanaVersion: String, id: String, licenseType: LicenseType? = nil, modified: Date, name: String? = nil, notificationDestinations: [NotificationDestinationType]? = nil, status: WorkspaceStatus, tags: [String: String]? = nil) {
            self.authentication = authentication
            self.created = created
            self.description = description
            self.endpoint = endpoint
            self.grafanaToken = grafanaToken
            self.grafanaVersion = grafanaVersion
            self.id = id
            self.licenseType = licenseType
            self.modified = modified
            self.name = name
            self.notificationDestinations = notificationDestinations
            self.status = status
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case authentication = "authentication"
            case created = "created"
            case description = "description"
            case endpoint = "endpoint"
            case grafanaToken = "grafanaToken"
            case grafanaVersion = "grafanaVersion"
            case id = "id"
            case licenseType = "licenseType"
            case modified = "modified"
            case name = "name"
            case notificationDestinations = "notificationDestinations"
            case status = "status"
            case tags = "tags"
        }
    }
}

// MARK: - Errors

/// Error enum for Grafana
public struct GrafanaErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize Grafana
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    /// You do not have sufficient permissions to perform this action.
    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    /// A resource was in an inconsistent state during an update or a deletion.
    public static var conflictException: Self { .init(.conflictException) }
    /// Unexpected error while processing the request. Retry the request.
    public static var internalServerException: Self { .init(.internalServerException) }
    /// The request references a resource that does not exist.
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    /// The request would cause a service quota to be exceeded.
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    /// The request was denied because of request throttling. Retry the request.
    public static var throttlingException: Self { .init(.throttlingException) }
    /// The value of a parameter in the request caused an error.
    public static var validationException: Self { .init(.validationException) }
}

extension GrafanaErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "ConflictException": Grafana.ConflictException.self,
        "InternalServerException": Grafana.InternalServerException.self,
        "ResourceNotFoundException": Grafana.ResourceNotFoundException.self,
        "ServiceQuotaExceededException": Grafana.ServiceQuotaExceededException.self,
        "ThrottlingException": Grafana.ThrottlingException.self,
        "ValidationException": Grafana.ValidationException.self
    ]
}

extension GrafanaErrorType: Equatable {
    public static func == (lhs: GrafanaErrorType, rhs: GrafanaErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension GrafanaErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
